package com.excesys.exsecs.linkage.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.excesys.exsecs.access.constant.RedisConstant;
import com.excesys.exsecs.access.entity.AccessDeviceInfo;
import com.excesys.exsecs.access.entity.AccessThingModel;
import com.excesys.exsecs.access.service.AccessDeviceInfoService;
import com.excesys.exsecs.access.service.AccessThingModelService;
import com.excesys.exsecs.access.vo.ThingInvokeVO;
import com.excesys.exsecs.admin.api.entity.SysDictItem;
import com.excesys.exsecs.admin.api.vo.UserVO;
import com.excesys.exsecs.admin.service.SysDictItemService;
import com.excesys.exsecs.admin.service.SysUserService;
import com.excesys.exsecs.alarm.entity.AlarmRecord;
import com.excesys.exsecs.alarm.entity.AlarmTypeConf;
import com.excesys.exsecs.alarm.service.AlarmRecordService;
import com.excesys.exsecs.alarm.service.AlarmTypeConfService;
import com.excesys.exsecs.common.security.util.SecurityUtils;
import com.excesys.exsecs.linkage.alarm.TencentEnterpriseEmailSender;
import com.excesys.exsecs.linkage.entity.*;
import com.excesys.exsecs.linkage.mapper.*;
import com.excesys.exsecs.linkage.service.SceneLinkageLogService;
import com.excesys.exsecs.linkage.service.SceneLinkageService;
import com.excesys.exsecs.linkage.vo.ConditionVo;
import com.excesys.exsecs.linkage.vo.SceneLinkageVO;
import com.excesys.exsecs.scada.entity.ScadaFolderAndLinked;
import com.excesys.exsecs.scada.mapper.ScadaFolderAndLinkedMapper;
import com.excesys.exsecs.scada.service.ScadaFolderAndLinkedService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 场景联动
 *
 * @author zhangtailong
 * @date 2024-05-20 14:09:13
 */
@Service
public class SceneLinkageServiceImpl extends ServiceImpl<SceneLinkageMapper, SceneLinkage> implements SceneLinkageService {


    //场景触发器
    @Autowired
    private SceneTriggerMapper sceneTriggerMapper;

	@Autowired
	private SceneTriggerTimeMapper sceneTriggerTimeMapper;
    //场景执行动作
    @Autowired
    private SceneExecuteActionMapper sceneExecuteActionMapper;
    //场景执行条件
    @Autowired
    private SceneExecuteConditionsMapper sceneExecuteConditionsMapper;
    //操作日志
    @Autowired
    private OperateLogsMapper operateLogsMapper;

	@Autowired
	private SceneExecuteActionModelMapper sceneExecuteActionModelMapper;
	@Autowired
	private ScadaFolderAndLinkedMapper scadaFolderAndLinkedMapper;
	@Autowired
	private StringRedisTemplate redisTemplate;
	@Autowired
	private AccessDeviceInfoService accessDeviceInfoService;

	@Autowired
	private AccessThingModelService accessThingModelService;
	@Autowired
	private AlarmTypeConfService alarmTypeConfService;
	@Autowired
	private SysDictItemService sysDictItemService;
	@Autowired
	private AlarmRecordService alarmRecordService;
	@Autowired
	private SceneLinkageLogService sceneLinkageLogService;
	@Autowired
	private ScadaFolderAndLinkedService service;
	@Autowired
	private SysUserService userService;

	@Autowired
	private TencentEnterpriseEmailSender sender;

    //新增场景
    @Override
    public Map saveOrUpdate(SceneLinkageVO sceneLinkageVO) {
        Map map = new HashMap();
        String msg = "";
        if (sceneLinkageVO != null) {
            OperateLogs operateLogs = new OperateLogs();
			String formatDateTime2 = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
			String linkageId = "CJ" + formatDateTime2 + RandomUtil.randomString(5);
            //判断联动编号是否为空 不为空删除 为空新增
            if (sceneLinkageVO.getLinkageId() != "") {
                this.getBaseMapper().delete(Wrappers.lambdaQuery(SceneLinkage.class).eq(Objects.nonNull(sceneLinkageVO.getLinkageId()), SceneLinkage::getLinkageId, sceneLinkageVO.getLinkageId()));
                this.sceneTriggerMapper.delete(Wrappers.lambdaQuery(SceneTrigger.class).eq(Objects.nonNull(sceneLinkageVO.getLinkageId()), SceneTrigger::getLinkageId, sceneLinkageVO.getLinkageId()));
				this.sceneTriggerTimeMapper.delete(Wrappers.lambdaQuery(SceneTriggerTime.class).eq(Objects.nonNull(sceneLinkageVO.getLinkageId()), SceneTriggerTime::getLinkageId, sceneLinkageVO.getLinkageId()));
				this.sceneExecuteActionMapper.delete(Wrappers.lambdaQuery(SceneExecuteAction.class).eq(Objects.nonNull(sceneLinkageVO.getLinkageId()), SceneExecuteAction::getLinkageId, sceneLinkageVO.getLinkageId()));
				this.sceneExecuteActionModelMapper.delete(Wrappers.lambdaQuery(SceneExecuteActionModel.class).eq(Objects.nonNull(sceneLinkageVO.getLinkageId()), SceneExecuteActionModel::getLinkageId, sceneLinkageVO.getLinkageId()));
				this.sceneExecuteConditionsMapper.delete(Wrappers.lambdaQuery(SceneExecuteConditions.class).eq(Objects.nonNull(sceneLinkageVO.getLinkageId()), SceneExecuteConditions::getLinkageId, sceneLinkageVO.getLinkageId()));
				if(ObjectUtil.isNotEmpty(sceneLinkageVO.getParentId())){
					this.scadaFolderAndLinkedMapper.delete(Wrappers.lambdaQuery(ScadaFolderAndLinked.class).eq(Objects.nonNull(sceneLinkageVO.getLinkageId()), ScadaFolderAndLinked::getLinkedId, sceneLinkageVO.getLinkageId()));
				}
				operateLogs.setTitle("(修改)" + sceneLinkageVO.getSceneName());//日志内容
                msg = "修改成功";
                map.put("msg", msg);
				service.updateById(linkageId,sceneLinkageVO.getId());
            } else {
                operateLogs.setTitle("(新增)" + sceneLinkageVO.getSceneName());//日志内容
                msg = "新增成功";
                map.put("msg", msg);
            }
            //场景联动
            SceneLinkage sceneLinkage = new SceneLinkage();
            sceneLinkage.setLinkageId(linkageId);//联动id  联动编号 主键
			sceneLinkage.setType(sceneLinkageVO.getType());
            sceneLinkage.setSceneName(sceneLinkageVO.getSceneName());//场景名称
            sceneLinkage.setDescription(sceneLinkageVO.getDescription());//场景描述
			sceneLinkage.setActionType(sceneLinkageVO.getActionType());//业务类型
            sceneLinkage.setStatus(2);//运行状态 （1启动  2 停止 ）
            this.getBaseMapper().insert(sceneLinkage);
			if(ObjectUtil.isNotEmpty(sceneLinkageVO.getParentId())){
				ScadaFolderAndLinked scadaFolderAndLinked = new ScadaFolderAndLinked();
				scadaFolderAndLinked.setLinkedId(sceneLinkage.getLinkageId());
				scadaFolderAndLinked.setParentId(sceneLinkageVO.getParentId());
				this.scadaFolderAndLinkedMapper.insert(scadaFolderAndLinked);
			}else{
			List<ScadaFolderAndLinked> scadaFolderAndLinkeds = 	this.scadaFolderAndLinkedMapper.queryById(sceneLinkageVO.getLinkageId());
			for(ScadaFolderAndLinked scadaFolderAndLinked :scadaFolderAndLinkeds){
				this.scadaFolderAndLinkedMapper.updateById(linkageId, Math.toIntExact(scadaFolderAndLinked.getId()));
			}
			}
            //场景触发器
            sceneLinkageVO.getSceneTriggerList().forEach(sceneTrigger -> {
                sceneTrigger.setLinkageId(linkageId);
				if(ObjectUtil.isEmpty(sceneTrigger.getIntervalTime())){
					sceneTrigger.setIntervalTime("");
				}
                this.sceneTriggerMapper.insert(sceneTrigger);
				if(ObjectUtil.isNotEmpty(sceneTrigger.getSpecialDateList())){
					sceneTrigger.getSpecialDateList().forEach(sceneTriggerTime->{
						sceneTriggerTime.setLinkageId(sceneTrigger.getLinkageId()+"");
						this.sceneTriggerTimeMapper.insert(sceneTriggerTime);
					});
				}
            });
            //场景执行动作
            sceneLinkageVO.getSceneExecuteActionList().forEach(sceneAction -> {
                sceneAction.setLinkageId(linkageId);
                this.sceneExecuteActionMapper.insert(sceneAction);
				if(ObjectUtil.isNotEmpty(sceneAction.getSceneExecuteActionModelList())){
					sceneAction.getSceneExecuteActionModelList().forEach(sceneExecuteActionModel->{
						sceneExecuteActionModel.setActionId(sceneAction.getId()+"");
						sceneExecuteActionModel.setLinkageId(sceneAction.getLinkageId()+"");
						this.sceneExecuteActionModelMapper.insert(sceneExecuteActionModel);
					});
				}

            });
            //场景执行条件
            sceneLinkageVO.getSceneExecuteConditionsList().forEach(sceneCondition -> {
                sceneCondition.setLinkageId(linkageId);
                this.sceneExecuteConditionsMapper.insert(sceneCondition);
            });

            LambdaUpdateWrapper<OperateLogs> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(OperateLogs::getServiceId, sceneLinkageVO.getLinkageId()) // 设置更新条件
                    .set(OperateLogs::getServiceId, linkageId);   // 设置要更新的字段和值
            this.operateLogsMapper.update(updateWrapper);
            operateLogs.setServiceId(linkageId);
            operateLogs.setLogType("1");//日志类型(1规则引擎，2....)
            //操作日志
            this.operateLogsMapper.insert(operateLogs);
        }
        return map;
    }


    @Override
    public SceneLinkageVO getByLinkageId(String linkageId) {
        SceneLinkageVO sceneLinkageVO = new SceneLinkageVO();
        if (linkageId != null) {
            SceneLinkage sceneLinkage = getBaseMapper().selectOne(Wrappers.lambdaQuery(SceneLinkage.class).eq(Objects.nonNull(linkageId), SceneLinkage::getLinkageId, linkageId));
            if (sceneLinkage != null) {
                sceneLinkageVO.setSceneName(sceneLinkage.getSceneName());
                sceneLinkageVO.setDescription(sceneLinkage.getDescription());
				sceneLinkageVO.setType(sceneLinkage.getType());
				sceneLinkageVO.setActionType(sceneLinkage.getActionType());
                //场景触发器
                sceneLinkageVO.setSceneTriggerList(sceneTriggerMapper.getInfoById(linkageId));
                //场景执行动作
				ConditionVo conditionVo = new ConditionVo();
				conditionVo.setLinkageId(linkageId);
                sceneLinkageVO.setSceneExecuteActionList(sceneExecuteActionMapper.getInfoById(conditionVo));
                //场景执行条件
                sceneLinkageVO.setSceneExecuteConditionsList(sceneExecuteConditionsMapper.selectList(Wrappers.lambdaQuery(SceneExecuteConditions.class).eq(Objects.nonNull(linkageId), SceneExecuteConditions::getLinkageId, linkageId)));
            }
        }
        return sceneLinkageVO;
    }

    @Override
    public boolean removeBatchByLinkageId(String linkageId) {
        if (linkageId != null) {
            int linkage = this.getBaseMapper().delete(Wrappers.lambdaQuery(SceneLinkage.class).eq(Objects.nonNull(linkageId), SceneLinkage::getLinkageId, linkageId));
            int trigger = this.sceneTriggerMapper.delete(Wrappers.lambdaQuery(SceneTrigger.class).eq(Objects.nonNull(linkageId), SceneTrigger::getLinkageId, linkageId));
			int triggertime = this.sceneTriggerTimeMapper.delete(Wrappers.lambdaQuery(SceneTriggerTime.class).eq(Objects.nonNull(linkageId), SceneTriggerTime::getLinkageId, linkageId));
            int action = this.sceneExecuteActionMapper.delete(Wrappers.lambdaQuery(SceneExecuteAction.class).eq(Objects.nonNull(linkageId), SceneExecuteAction::getLinkageId, linkageId));
			int model = this.sceneExecuteActionModelMapper.delete(Wrappers.lambdaQuery(SceneExecuteActionModel.class).eq(Objects.nonNull(linkageId), SceneExecuteActionModel::getLinkageId, linkageId));
            int conditions = this.sceneExecuteConditionsMapper.delete(Wrappers.lambdaQuery(SceneExecuteConditions.class).eq(Objects.nonNull(linkageId), SceneExecuteConditions::getLinkageId, linkageId));
            this.operateLogsMapper.delete(Wrappers.lambdaQuery(OperateLogs.class).eq(Objects.nonNull(linkageId), OperateLogs::getServiceId, linkageId));

            if (linkage > 0 && trigger > 0 && action > 0 && conditions > 0 && triggertime>0 && model>0) {
                return true;
            }
        }
        return false;
    }

    @Override
    public int updateStatus(String linkageId, Integer status) {
        OperateLogs operateLogs = new OperateLogs();
        operateLogs.setServiceId(linkageId);
        operateLogs.setLogType("1");//日志类型(1规则引擎，2....)
        // 使用LambdaUpdateWrapper来构建更新条件
        LambdaUpdateWrapper<SceneLinkage> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(SceneLinkage::getLinkageId, linkageId) // 设置更新条件
                .set(SceneLinkage::getStatus, status);     // 设置要更新的字段和值
        // 调用update方法，传入更新条件
        int result = this.getBaseMapper().update(updateWrapper);
        // 处理更新结果，例如检查是否更新成功（result > 0）
        if (result > 0) {
            if (status.equals(1)) {
                operateLogs.setTitle("启动成功");//日志内容
            } else {
                operateLogs.setTitle("停止成功");//日志内容
            }
            //操作日志
            this.operateLogsMapper.insert(operateLogs);
        } else {
            if (status.equals(1)) {
                operateLogs.setTitle("启动失败");//日志内容
            } else {
                operateLogs.setTitle("停止失败");//日志内容
            }
            //操作日志
            this.operateLogsMapper.insert(operateLogs);
        }
        return result;
    }

    @Override
    public Page<List<OperateLogs>> getLog(Page page, String linkageId) {
        LambdaQueryWrapper<OperateLogs> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(Objects.nonNull(linkageId), OperateLogs::getServiceId, linkageId);
        // 根据 SceneLinkage 的某个字段（例如 id）进行升序排序
        wrapper.orderByDesc(OperateLogs::getId);
        return  this.operateLogsMapper.selectPage(page,wrapper);
    }

	@Override
	public boolean operate(String linkageId) throws Exception {
		boolean timeFlag = false;
		Boolean conditionFlag = false;
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
		SceneLinkageVO sceneLinkageVO = this.getByLinkageId(linkageId);
		List<SceneExecuteAction> actions = sceneLinkageVO.getSceneExecuteActionList();
		List<Boolean> booleanList = new ArrayList<>();
		List<String> unitNos = new ArrayList<>();
		String alarmId = "";
		if(sceneLinkageVO.getSceneExecuteConditionsList().size()>0){
			boolean status =false;
			List<SceneExecuteConditions> secList = new ArrayList<>();
			List<SceneExecuteConditions> sceneExecuteConditionsList = 	sceneLinkageVO.getSceneExecuteConditionsList();
			for (SceneExecuteConditions sceneExecuteCondition : sceneExecuteConditionsList) {
				//执行条件（ 0: 全部条件  1: 任意一个条件）
				if (sceneExecuteCondition.getConditions() == 1) {
					//判断是设备还是时间  1-设备 2-时间
					if (sceneExecuteCondition.getTriggerMode() == 1) {
						if (ObjectUtil.isNotEmpty(sceneExecuteCondition.getUnitNo())) {
							String[] uniiNos = sceneExecuteCondition.getUnitNo().split(",");
							for (String unitNo : uniiNos) {
								SceneExecuteConditions sceneExecuteCondition1 = new SceneExecuteConditions();
								BeanUtils.copyProperties(sceneExecuteCondition, sceneExecuteCondition1);
								sceneExecuteCondition1.setUnitNo(unitNo);
								Object objData = redisTemplate.opsForHash().get(RedisConstant.REPORT_LIST_KEY, unitNo);
								if (ObjectUtil.isNotEmpty(objData)) {
									JSONObject jsonObject = new JSONObject(objData);
									Map map = (Map) jsonObject.get("data");
									JSONObject jso = new JSONObject();
									jso.set("nowValue",map.get(sceneExecuteCondition.getChannelNo()) + "");
									if("online".equals(sceneExecuteCondition.getChannelNo())){
										String online  = jsonObject.get("online")+"";
										if(online.equals(sceneExecuteCondition.getFixedValue())){
											conditionFlag = true;
											break;
										}
									}
									JSONArray jsonArray = getJson(unitNo);
									if (ObjectUtil.isNotEmpty(jsonArray)) {
										for (int i = 0; i < jsonArray.size(); i++) {
											JSONObject json1 = new JSONObject(jsonArray.get(i));
											if (json1.get("identifier").equals(sceneExecuteCondition.getChannelNo())) {
												JSONObject json2 = new JSONObject(json1.get("dataType"));
												if (ObjectUtil.isNotEmpty(json2.get("type"))) {
													if (ObjectUtil.isNotEmpty(json2.get("type"))) {
														if (ObjectUtil.isNotEmpty(objData)) {
															if (getBoolean(json2.get("type"), sceneExecuteCondition, map)) {
																conditionFlag = true;
																if (sceneExecuteCondition.getConfigType() != 3 ||sceneExecuteCondition.getConfigType() != 6) {
																	sceneExecuteCondition1.setVal(jso);
																}
																secList.add(sceneExecuteCondition1);
																execute(secList,actions,sceneLinkageVO);
																status =true;
																break;
															}
														} else {
															continue;
														}
													} else {
														continue;
													}
												}
											}
										}

									}
								}
								if(status){
									break;
								}
							}
						}


					} else if (sceneExecuteCondition.getTriggerMode() == 2) {
						List<SceneExecuteConditions> sceneExecuteActions = new ArrayList<>();
						if ("1".equals(sceneExecuteCondition.getTimeScope())) {
							LocalDateTime start1Time = LocalDateTime.parse(sceneExecuteCondition.getStartTime() + "", formatter);
							LocalDateTime end1Time = LocalDateTime.parse(sceneExecuteCondition.getEndTime() + "", formatter);
							// 获取当前时间
							LocalDateTime now = LocalDateTime.now();
							// 判断当前时间是否在时间范围内
							if (!now.isBefore(start1Time) && !now.isAfter(end1Time)) {;
								execute(sceneExecuteActions,actions,sceneLinkageVO);
							}
						} else {
							execute(sceneExecuteActions,actions,sceneLinkageVO);
						}
					}
				} else if (sceneExecuteCondition.getConditions() == 0) {
					//判断是设备还是时间  1-设备 2-时间
					if (sceneExecuteCondition.getTriggerMode() == 1) {
						if (ObjectUtil.isNotEmpty(sceneExecuteCondition.getUnitNo())) {
							String[] uniiNos = sceneExecuteCondition.getUnitNo().split(",");
							for (String unitNo : uniiNos) {
								SceneExecuteConditions sceneExecuteCondition1 = new SceneExecuteConditions();
								BeanUtils.copyProperties(sceneExecuteCondition, sceneExecuteCondition1);
								sceneExecuteCondition1.setUnitNo(unitNo);
								Object objData = redisTemplate.opsForHash().get(RedisConstant.REPORT_LIST_KEY, unitNo);
								if (ObjectUtil.isNotEmpty(objData)) {
									JSONObject jsonObject = new JSONObject(objData);
									Map map = (Map) jsonObject.get("data");
									JSONObject jso = new JSONObject();
									jso.set("nowValue",map.get(sceneExecuteCondition.getChannelNo()) + "");
									JSONArray jsonArray = getJson(unitNo);
									if("online".equals(sceneExecuteCondition.getChannelNo())){
										String online  = jsonObject.get("online")+"";
										if(online.equals(sceneExecuteCondition.getFixedValue())){
											booleanList.add(true);
										}else{
											booleanList.add(false);
										}
									}
									if (ObjectUtil.isNotEmpty(jsonArray)) {
										for (int i = 0; i < jsonArray.size(); i++) {
											JSONObject json1 = new JSONObject(jsonArray.get(i));
											if (json1.get("identifier").equals(sceneExecuteCondition.getChannelNo())) {
												JSONObject json2 = new JSONObject(json1.get("dataType"));
												if (ObjectUtil.isNotEmpty(json2.get("type"))) {
													if (ObjectUtil.isNotEmpty(json2.get("type"))) {
														if (ObjectUtil.isNotEmpty(objData)) {
															if (getBoolean(json2.get("type"), sceneExecuteCondition, map)) {
																booleanList.add(true);
																if (sceneExecuteCondition.getConfigType() != 3 ||sceneExecuteCondition.getConfigType() != 6) {
																	sceneExecuteCondition1.setVal(jso);
																}
																secList.add(sceneExecuteCondition1);
																break;
															}else{
																booleanList.add(false);
																break;
															}
														}
													}
												}
											}
										}
									}
								}
							}
						}

					} else if (sceneExecuteCondition.getTriggerMode() == 2) {
						if ("1".equals(sceneExecuteCondition.getTimeScope())) {
							LocalDateTime start1Time = LocalDateTime.parse(sceneExecuteCondition.getStartTime(), formatter);
							LocalDateTime end1Time = LocalDateTime.parse(sceneExecuteCondition.getEndTime(), formatter);
							// 获取当前时间
							LocalDateTime now = LocalDateTime.now();
							// 判断当前时间是否在时间范围内
							if (!now.isBefore(start1Time) && !now.isAfter(end1Time)) {
								timeFlag = true;
							}
						} else {
							timeFlag = true;
						}
					}
					if (sceneExecuteConditionsList.indexOf(sceneExecuteCondition) == sceneExecuteConditionsList.size() - 1) {
						if(!booleanList.contains(false)){
							conditionFlag =true;
						}
						booleanList.clear();
						if (conditionFlag || timeFlag) {
							execute(secList,actions,sceneLinkageVO);
						}else {
							SceneLinkageLog sceneLinkageLog = new SceneLinkageLog();
							sceneLinkageLog.setLinkageId(sceneLinkageVO.getLinkageId());
							sceneLinkageLog.setSceneName(sceneLinkageVO.getSceneName());
							sceneLinkageLog.setStatus(0);
							sceneLinkageLog.setHappenTime(LocalDateTime.now());
							sceneLinkageLog.setInfo("手动触发");
							sceneLinkageLog.setRemarks("执行条件校验失败");
							sceneLinkageLogService.save(sceneLinkageLog);
						}
					}

				}
			}
		}else{
			for(SceneExecuteAction sceneExecuteAction: actions){
				ThingInvokeVO thingInvokeVO = new ThingInvokeVO();
				thingInvokeVO.setService(sceneExecuteAction.getIdentifier());
				thingInvokeVO.setTimestamp(System.currentTimeMillis());
				//执行动作模式 （1设备输出  2关联告警 3消息发送）
				if (sceneExecuteAction.getTriggerMode() == 1) {
					JSONObject jsonObject = new JSONObject();
					for (SceneExecuteActionModel model : sceneExecuteAction.getSceneExecuteActionModelList()) {
						String[] uniiNos = sceneExecuteAction.getUnitNo().split(",");
						for(String unitNO : uniiNos){
							// 如果设备离线，则直接返回离线信息
							AccessDeviceInfo device = accessDeviceInfoService.getOne(Wrappers.<AccessDeviceInfo>lambdaQuery().eq(AccessDeviceInfo::getUnitNo, unitNO));
							thingInvokeVO.setUnitNo(unitNO);
							if (device.getOnlineStatus() != 0) {
								if ("int32".equals(model.getType())) {
									jsonObject.put(model.getCircuitId(), Integer.valueOf(model.getValue()));
								} else if ("float".equals(model.getType())) {
									jsonObject.put(model.getCircuitId(), Float.valueOf(model.getValue()));
								} else if ("bool".equals(model.getType())) {
									if ("1".equals(model.getValue())) {
										jsonObject.put(model.getCircuitId(), Boolean.TRUE);
									} else {
										jsonObject.put(model.getCircuitId(), Boolean.FALSE);
									}
								} else if ("enum".equals(model.getType())) {
									jsonObject.put(model.getCircuitId(), Integer.valueOf(model.getValue()));
								} else if ("text".equals(model.getType())) {
									jsonObject.put(model.getCircuitId(), String.valueOf(model.getValue()));
								}
							}
							thingInvokeVO.setArgs(jsonObject);
							if(ObjectUtil.isNotEmpty(sceneExecuteAction.getDelayTime())){
								Thread.sleep(Integer.valueOf(sceneExecuteAction.getDelayTime())*1000);
							}
							ThingInvokeVO thingInvokeVO1 = accessDeviceInfoService.invoke(thingInvokeVO);
							System.out.println("thingInvokeVO1:" + thingInvokeVO1);
						}
					}
				} else if (sceneExecuteAction.getTriggerMode() == 2) {
					alarmId = sceneExecuteAction.getAlarmId();
					//根据告警类型走
					AlarmTypeConf alarmTypeConf = alarmTypeConfService.getTypeByCode(sceneExecuteAction.getAlarmId());
					SysDictItem sysDictItem = sysDictItemService.getById(sceneExecuteAction.getAlarmInfo());
					AlarmRecord alarmRecord = new AlarmRecord();
					alarmRecord.setAlarmContent(sysDictItem.getLabel());
				//	alarmRecord.setUnitNo(sceneTrigger.getUnitNo());
					alarmRecord.setAlarmTypeCode(alarmTypeConf.getTypeCode());
					alarmRecord.setAlarmLevel(Integer.valueOf(alarmTypeConf.getLevel()));
					alarmRecord.setSender(alarmTypeConf.getSender());
				//	alarmRecord.setConfigType(sceneTrigger.getConfigType());
					alarmRecord.setHappenTime(LocalDateTime.now());
				//	alarmRecord.setUnit(sceneTrigger.getUnit());
				//	if (sceneTrigger.getConfigType() != 3 || sceneTrigger.getConfigType() != 6) {
				//		alarmRecord.setAlarmValue(sceneTrigger.getVal().get("nowValue") + "");
				//	} else {
				//		alarmRecord.setLowerValue(sceneTrigger.getLowerValue());
				//		alarmRecord.setUpperValue(sceneTrigger.getUpperValue());
				//	}

					if(ObjectUtil.isNotEmpty(sceneExecuteAction.getDelayTime())){
						Thread.sleep(Integer.valueOf(sceneExecuteAction.getDelayTime())*1000);
					}
					Boolean status = alarmRecordService.saveRecord(alarmRecord);
					SceneLinkageLog sceneLinkageLog = new SceneLinkageLog();
					sceneLinkageLog.setLinkageId(linkageId);
					sceneLinkageLog.setSceneName(sceneLinkageVO.getSceneName());
					sceneLinkageLog.setHappenTime(LocalDateTime.now());
					sceneLinkageLog.setInfo("手动触发");
					if(status){
						sceneLinkageLog.setStatus(1);
						sceneLinkageLog.setRemarks("手动触发执行动作成功");
					}else{
						sceneLinkageLog.setStatus(0);
						sceneLinkageLog.setRemarks("手动触发执行动作失败");
					}
					sceneLinkageLogService.save(sceneLinkageLog);
				}
			}
			//推送告警
			String body = "无触发器执行条件手动执行规则引擎";
			AlarmTypeConf alarmTypeConf1 =	alarmTypeConfService.getTypeByCode(alarmId);
			if(alarmTypeConf1.getWay().contains("sms")){
				for(int i=0;i<alarmTypeConf1.getSenderList().length;i++){
					UserVO userVO  = userService.selectUserVoById(Long.valueOf(alarmTypeConf1.getSenderList()[i]));
					if(ObjectUtil.isNotEmpty(userVO.getEmail())){
						sender.sendMsg(userVO.getEmail(),body);
					}
				}
			}
		}
		return true;
	}

	private void execute(List<SceneExecuteConditions> secList,List<SceneExecuteAction> actions, SceneLinkageVO sceneLinkageVO) throws Exception {
		Boolean status = true;
		Boolean status1 =true;
		String Linked = "";
		List<Boolean> booleanList = new ArrayList<>();
		List<String> unitNos = new ArrayList<>();
		String alarmId = "";
		if(secList.size()>0){
				for (SceneExecuteConditions sec : secList) {
					ConditionVo conditionVo = new ConditionVo();
					conditionVo.setLinkageId(sec.getLinkageId());
					List<SceneExecuteAction> sceneExecuteActions = sceneExecuteActionMapper.getInfoById(conditionVo);
					//根据执行条件任意一个或全部判断执行下一步
					for (SceneExecuteAction sceneExecuteAction : sceneExecuteActions) {
						Linked = sceneExecuteAction.getLinkageId();
						ThingInvokeVO thingInvokeVO = new ThingInvokeVO();
						thingInvokeVO.setService(sceneExecuteAction.getIdentifier());
						thingInvokeVO.setTimestamp(System.currentTimeMillis());
						//执行动作模式 （1设备输出  2关联告警 3消息发送）
						if (sceneExecuteAction.getTriggerMode() == 1) {
							JSONObject jsonObject = new JSONObject();
							for (SceneExecuteActionModel model : sceneExecuteAction.getSceneExecuteActionModelList()) {
								String[] uniiNos = sceneExecuteAction.getUnitNo().split(",");
								for(String unitNO : uniiNos){
									thingInvokeVO.setUnitNo(unitNO);
									// 如果设备离线，则直接返回离线信息
									AccessDeviceInfo device = accessDeviceInfoService.getOne(Wrappers.<AccessDeviceInfo>lambdaQuery().eq(AccessDeviceInfo::getUnitNo, unitNO));
									if (device.getOnlineStatus() != 0) {
										if ("int32".equals(model.getType())) {
											jsonObject.put(model.getCircuitId(), Integer.valueOf(model.getValue()));
										} else if ("float".equals(model.getType())) {
											jsonObject.put(model.getCircuitId(), Float.valueOf(model.getValue()));
										} else if ("bool".equals(model.getType())) {
											if ("1".equals(model.getValue())) {
												jsonObject.put(model.getCircuitId(), Boolean.TRUE);
											} else {
												jsonObject.put(model.getCircuitId(), Boolean.FALSE);
											}
										} else if ("enum".equals(model.getType())) {
											jsonObject.put(model.getCircuitId(), Integer.valueOf(model.getValue()));
										} else if ("text".equals(model.getType())) {
											jsonObject.put(model.getCircuitId(), String.valueOf(model.getValue()));
										}
									}
								}
							}
							thingInvokeVO.setArgs(jsonObject);
							if (ObjectUtil.isNotEmpty(sceneExecuteAction.getDelayTime())) {
								Thread.sleep(Integer.valueOf(sceneExecuteAction.getDelayTime()) * 1000);
							}
							ThingInvokeVO thingInvokeVO1 = accessDeviceInfoService.invoke(thingInvokeVO);
							System.out.println("thingInvokeVO1:" + thingInvokeVO1);
						} else if (sceneExecuteAction.getTriggerMode() == 2) {
							alarmId = sceneExecuteAction.getAlarmId();
							unitNos.add(sec.getUnitNo());
							//根据告警类型走
							AlarmTypeConf alarmTypeConf =  alarmTypeConfService.getTypeByCode(sceneExecuteAction.getAlarmId());
							SysDictItem sysDictItem = sysDictItemService.getById(sceneExecuteAction.getAlarmInfo());
							AlarmRecord alarmRecord = new AlarmRecord();
							alarmRecord.setAlarmContent(sysDictItem.getLabel());
							alarmRecord.setUnitNo(sec.getUnitNo());
							alarmRecord.setAlarmTypeCode(alarmTypeConf.getTypeCode());
							alarmRecord.setAlarmLevel(Integer.valueOf(alarmTypeConf.getLevel()));
							alarmRecord.setSender(alarmTypeConf.getSender());
							alarmRecord.setConfigType(sec.getConfigType());
							alarmRecord.setHappenTime(sec.getTimeStamp());
							alarmRecord.setUnit(sec.getUnit());
							alarmRecord.setCreateBy(SecurityUtils.getUser()+"");
							alarmRecord.setUpdateBy(SecurityUtils.getUser()+"");
							alarmRecord.setHappenTime(LocalDateTime.now());
							if (sec.getConfigType() != 3 ||sec.getConfigType() != 6) {
								alarmRecord.setAlarmValue(sec.getVal().get("nowValue")+"");
								alarmRecord.setFixedValue(sec.getFixedValue());
							} else {
								alarmRecord.setLowerValue(sec.getLowerValue());
								alarmRecord.setUpperValue(sec.getUpperValue());
							}
							if(ObjectUtil.isNotEmpty(sceneExecuteAction.getDelayTime())){
								Thread.sleep(Integer.valueOf(sceneExecuteAction.getDelayTime())*1000);
							}
							status = alarmRecordService.saveRecord(alarmRecord);
							booleanList.add(status);
						}
					}
				}
			SceneLinkageLog sceneLinkageLog = new SceneLinkageLog();
			sceneLinkageLog.setLinkageId(Linked);
			sceneLinkageLog.setSceneName(sceneLinkageVO.getSceneName());
			sceneLinkageLog.setHappenTime(LocalDateTime.now());
			sceneLinkageLog.setInfo("手动触发");
			if(!booleanList.contains(false)){
				sceneLinkageLog.setStatus(1);
				sceneLinkageLog.setRemarks("执行动作成功");
			}else{
				sceneLinkageLog.setStatus(0);
				sceneLinkageLog.setRemarks("执行动作插入告警失败");
			}
			sceneLinkageLogService.save(sceneLinkageLog);

			}else{
			for(SceneExecuteAction sceneExecuteAction: actions){
				ThingInvokeVO thingInvokeVO = new ThingInvokeVO();
				thingInvokeVO.setService(sceneExecuteAction.getIdentifier());
				thingInvokeVO.setTimestamp(System.currentTimeMillis());
				//执行动作模式 （1设备输出  2关联告警 3消息发送）
				if (sceneExecuteAction.getTriggerMode() == 1) {
					JSONObject jsonObject = new JSONObject();
					for (SceneExecuteActionModel model : sceneExecuteAction.getSceneExecuteActionModelList()) {
						String[] uniiNos = sceneExecuteAction.getUnitNo().split(",");
						for(String unitNO : uniiNos){
							// 如果设备离线，则直接返回离线信息
							AccessDeviceInfo device = accessDeviceInfoService.getOne(Wrappers.<AccessDeviceInfo>lambdaQuery().eq(AccessDeviceInfo::getUnitNo, unitNO));
							thingInvokeVO.setUnitNo(unitNO);
							if (device.getOnlineStatus() != 0) {
								if ("int32".equals(model.getType())) {
									jsonObject.put(model.getCircuitId(), Integer.valueOf(model.getValue()));
								} else if ("float".equals(model.getType())) {
									jsonObject.put(model.getCircuitId(), Float.valueOf(model.getValue()));
								} else if ("bool".equals(model.getType())) {
									if ("1".equals(model.getValue())) {
										jsonObject.put(model.getCircuitId(), Boolean.TRUE);
									} else {
										jsonObject.put(model.getCircuitId(), Boolean.FALSE);
									}
								} else if ("enum".equals(model.getType())) {
									jsonObject.put(model.getCircuitId(), Integer.valueOf(model.getValue()));
								} else if ("text".equals(model.getType())) {
									jsonObject.put(model.getCircuitId(), String.valueOf(model.getValue()));
								}
							}
							thingInvokeVO.setArgs(jsonObject);
							if(ObjectUtil.isNotEmpty(sceneExecuteAction.getDelayTime())){
								Thread.sleep(Integer.valueOf(sceneExecuteAction.getDelayTime())*1000);
							}
							ThingInvokeVO thingInvokeVO1 = accessDeviceInfoService.invoke(thingInvokeVO);
							System.out.println("thingInvokeVO1:" + thingInvokeVO1);
						}
					}
				} else if (sceneExecuteAction.getTriggerMode() == 2) {
					alarmId = sceneExecuteAction.getAlarmId();
					//unitNos.add(sec.getUnitNo());
					//根据告警类型走
					AlarmTypeConf alarmTypeConf = alarmTypeConfService.getTypeByCode(sceneExecuteAction.getAlarmId());
					SysDictItem sysDictItem = sysDictItemService.getById(sceneExecuteAction.getAlarmInfo());
					AlarmRecord alarmRecord = new AlarmRecord();
					alarmRecord.setAlarmContent(sysDictItem.getLabel());
					//	alarmRecord.setUnitNo(sceneTrigger.getUnitNo());
					alarmRecord.setAlarmTypeCode(alarmTypeConf.getTypeCode());
					alarmRecord.setAlarmLevel(Integer.valueOf(alarmTypeConf.getLevel()));
					alarmRecord.setSender(alarmTypeConf.getSender());
					alarmRecord.setCreateBy(SecurityUtils.getUser()+"");
					alarmRecord.setUpdateBy(SecurityUtils.getUser()+"");
					alarmRecord.setHappenTime(LocalDateTime.now());
					//	alarmRecord.setConfigType(sceneTrigger.getConfigType());
					//	alarmRecord.setHappenTime(sceneTrigger.getTimeStamp());
					//	alarmRecord.setUnit(sceneTrigger.getUnit());
					//	if (sceneTrigger.getConfigType() != 3 || sceneTrigger.getConfigType() != 6) {
					//		alarmRecord.setAlarmValue(sceneTrigger.getVal().get("nowValue") + "");
					//	} else {
					//		alarmRecord.setLowerValue(sceneTrigger.getLowerValue());
					//		alarmRecord.setUpperValue(sceneTrigger.getUpperValue());
					//	}

					if(ObjectUtil.isNotEmpty(sceneExecuteAction.getDelayTime())){
						Thread.sleep(Integer.valueOf(sceneExecuteAction.getDelayTime())*1000);
					}
					status = alarmRecordService.saveRecord(alarmRecord);
					booleanList.add(status);
				} else if (sceneExecuteAction.getTriggerMode() == 3) {
				}
			}
			SceneLinkageLog sceneLinkageLog = new SceneLinkageLog();
			sceneLinkageLog.setLinkageId(Linked);
			sceneLinkageLog.setSceneName(sceneLinkageVO.getSceneName());
			sceneLinkageLog.setHappenTime(LocalDateTime.now());
			sceneLinkageLog.setInfo("手动触发");
			if(!booleanList.contains(false)){
				sceneLinkageLog.setStatus(1);
				sceneLinkageLog.setRemarks("执行动作成功");
			}else{
				sceneLinkageLog.setStatus(0);
				sceneLinkageLog.setRemarks("执行动作插入告警失败");
			}
			sceneLinkageLogService.save(sceneLinkageLog);
		}
		//推送告警
		String body = "该设备出现异常，请及时处理（手动触发）!";
		String head = "";
		if(unitNos.size()>0) {
			HashSet<String> set = new HashSet<>(unitNos);
			List<String> deduplicatedList = new ArrayList<>(set);
			for (int i = 0; i < deduplicatedList.size(); i++) {
				AccessDeviceInfo accessDeviceInfo = accessDeviceInfoService.detail(deduplicatedList.get(i));
				head = head + accessDeviceInfo.getDeviceName() + ",";
			}
			if (head.endsWith(",")) {
				head = head.substring(0, head.length() - 1);
			}
			body = head + body;
		}else{
			body = "";
		}
		AlarmTypeConf alarmTypeConf1 =	alarmTypeConfService.getTypeByCode(alarmId);
		if(ObjectUtil.isNotEmpty(alarmTypeConf1)){
			if(alarmTypeConf1.getWay().contains("sms")){
				for(int i=0;i<alarmTypeConf1.getSenderList().length;i++){
					UserVO userVO  = userService.selectUserVoById(Long.valueOf(alarmTypeConf1.getSenderList()[i]));
					if(ObjectUtil.isNotEmpty(userVO.getEmail())){
						sender.sendMsg(userVO.getEmail(),body);
					}
				}
			}
		}
	}

	private JSONArray getJson(String unitNo) {
		AccessDeviceInfo accessDeviceInfo = accessDeviceInfoService.detail(unitNo);
		AccessThingModel accessThingModel = accessThingModelService.getThingModelByProductKey(accessDeviceInfo.getProductKey());
		JSONObject json = accessThingModel.getModel();
		JSONArray jsonArray = (JSONArray) json.get("properties");
		return jsonArray;
	}

	private boolean getBoolean(Object obj, SceneExecuteConditions sceneExecuteCondition, Map map) {
		if ("int32".equals(obj)) {
			Integer nowValue = Integer.valueOf(map.get(sceneExecuteCondition.getChannelNo()) + "");
			//0-> 1-< 2-= 3-范围值
			if (sceneExecuteCondition.getConfigType() != 3) {
				Integer fixedValue = Integer.valueOf(sceneExecuteCondition.getFixedValue() + "");
				if (sceneExecuteCondition.getConfigType() == 0) {
					if (nowValue.compareTo(fixedValue) > 0) {
						return true;
					}
				} else if (sceneExecuteCondition.getConfigType() == 1) {
					if (nowValue.compareTo(fixedValue) < 0) {
						return true;
					}
				} else if (sceneExecuteCondition.getConfigType() == 2) {
					if (nowValue.compareTo(fixedValue) == 0) {
						return true;
					}
				}
			} else {
				if (sceneExecuteCondition.getConfigType() == 3) {
					Integer leftValue = Integer.valueOf(sceneExecuteCondition.getLowerValue());
					Integer rightValue = Integer.valueOf(sceneExecuteCondition.getUpperValue());
					if (leftValue.compareTo(nowValue) < 0 && rightValue.compareTo(nowValue) > 0) {
						return true;
					}
				}
			}
		} else if ("float".equals(obj)) {
			Float nowValue = Float.valueOf(map.get(sceneExecuteCondition.getChannelNo()) + "");
			//0-> 1-< 2-= 3-范围值
			if (sceneExecuteCondition.getConfigType() != 3) {
				Float fixedValue = Float.valueOf(sceneExecuteCondition.getFixedValue() + "");
				if (sceneExecuteCondition.getConfigType() == 0) {
					if (nowValue.compareTo(fixedValue) > 0) {
						return true;
					}
				} else if (sceneExecuteCondition.getConfigType() == 1) {
					if (nowValue.compareTo(fixedValue) < 0) {
						return true;
					}
				} else if (sceneExecuteCondition.getConfigType() == 2) {
					if (nowValue.compareTo(fixedValue) == 0) {
						return true;
					}
				}
			} else {
				if (sceneExecuteCondition.getConfigType() == 3) {
					Integer leftValue = Integer.valueOf(sceneExecuteCondition.getLowerValue());
					Integer rightValue = Integer.valueOf(sceneExecuteCondition.getUpperValue());
					if (leftValue < nowValue && rightValue > nowValue) {
						return true;
					}
				}
			}
		}
		return false;
	}


}